package datas

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
)

var (
	baseOptionsRe = regexp.MustCompile(`<.*>`)
)

func FromFlag() (runable *RunableFile) {
	runable = new(RunableFile)
	runable.Options = make(map[string]string)

	flag.VisitAll(func(oneflag *flag.Flag) {
		runable.Options[oneflag.Name] = oneflag.Usage
	})
	return
}

func (runable *RunableFile) Json() string {
	buf, _ := json.MarshalIndent(runable, "", "\t")
	return string(buf)
}

func FromHelpTest(executable string, options ...string) (runable *RunableFile) {
	runable = new(RunableFile)
	runable.Options = make(map[string]string)

	args := []string{"bash", "-c"}
	help := "-h"
	if options != nil {
		help = options[0]
	}
	// poc := make(map[string]interface{})

	if strings.HasSuffix(executable, ".py") {
		runable.Executable = Tui.Select("py3/py2", "python3", "python")
		args = append(args, strings.Join([]string{runable.Executable, executable, help}, " "))
	} else {
		if _, err := os.Stat(executable); err != nil {
			path, err := exec.LookPath(executable)
			if err != nil {
				log.Println("not found path:", executable)
				return
			}
			executable = path
		} else {
			runable.Executable = Tui.Select("raw bin/use bash run it?", "", "bash -c")
		}
		a, _ := filepath.Abs(executable)
		args = append(args, a+" "+help)
	}
	fmt.Println(strings.Join(args, " "))
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Stdin = os.Stdin
	outer2 := bytes.Buffer{}
	cmd.Stderr = &outer2
	out, err := cmd.Output()
	if err != nil {
		out = outer2.Bytes()
		if len(out) == 0 {
			log.Println(err)
			return
		}

	}

	opts := ParseOptions(string(out))
	runable.Options = opts
	runable.Name = filepath.Base(executable)
	runable.Path = executable
	// buf, _ := json.MarshalIndent(poc, "", "\t")
	return
}

func ParseOptions(payload string) (o map[string]string) {
	payload = baseOptionsRe.ReplaceAllString(payload, "")
	o = make(map[string]string)
	for _, line := range strings.Split(payload, "\n") {
		if len(line) < 2 {
			continue
		}
		if line[0:1] != " " && line[0:1] != "\t" {
			continue
		}
		line = strings.TrimSpace(line)
		if strings.HasSuffix(line, ":") {
			continue
		}
		if strings.HasPrefix(line, "-") && line[1:2] != " " {
			fs := strings.Fields(line)
			o[fs[0]] = strings.Join(fs[1:], " ")
		}
	}
	return
}

// func choose(label string, optiosn ...string) string {
// 	prompt := promptui.Select{
// 		// Label:        "Python3/python2",
// 		Label:        label,
// 		Items:        optiosn,
// 		HideSelected: true,
// 		Size:         10,
// 		Searcher: func(s string, ix int) bool {
// 			return strings.Contains(optiosn[ix], s)
// 		},
// 	}
// 	_, result, err := prompt.Run()
// 	if err != nil {
// 		return "python3"
// 	}
// 	return result
// }

// func MapToPrompt(a map[string]string) (o []prompt.Suggest) {
// 	for k, v := range a {
// 		o = append(o, prompt.Suggest{
// 			Text:        k,
// 			Description: v,
// 		})
// 	}
// 	return
// }
